#include "blurdialog.h"

/// Parameter: Slider's current value
/// Return:
/// Action: Sets the filter matrix
///         The slider has 3 values, one for small, medium, large filter matrix.
///         The bigger the matrix is, the more it blurs.
///         Runs the filter for the small size image to show preview of the transformation.
void BlurDialog::slider_changed(int)
{
    if (_slider->value() == 3)
    {
        float filterMatrix[9] =
        {
            0,  1,  0,
            1,  1,  1,
            0,  1,  0
        };

        if (_matrix != 0)
            delete[] _matrix;

        _matrix = new float[9];
        _matrixWidth = 3;
        std::copy(std::begin(filterMatrix), std::end(filterMatrix), _matrix);

        _filter->set_original_data((int*)_image.bits(), _image.width(), _image.height());
        _filter->set_filter_matrix(filterMatrix, 3);
        _filter->set_bias(0.0);
        _filter->set_factor(1.0 / 5);

        _modifiedImage = new QImage((uchar*)_filter->use_filter(),
                                    _image.width(), _image.height(), _image.format());
        _label->setPixmap(QPixmap::fromImage(*_modifiedImage));
    }
    else if (_slider->value() == 5)
    {
        float filterMatrix[25] =
        {
            0,  0,  1,  0,  0,
            0,  1,  1,  1,  0,
            1,  1,  1,  1,  1,
            0,  1,  1,  1,  0,
            0,  0,  1,  0,  0,
        };

        if (_matrix != 0)
            delete[] _matrix;

        _matrix = new float[25];
        _matrixWidth = 5;
        std::copy(std::begin(filterMatrix), std::end(filterMatrix), _matrix);

        _filter->set_original_data((int*)_image.bits(), _image.width(), _image.height());
        _filter->set_filter_matrix(filterMatrix, 5);
        _filter->set_bias(0.0);
        _filter->set_factor(1.0 / 13);

        _modifiedImage = new QImage((uchar*)_filter->use_filter(),
                                    _image.width(), _image.height(), _image.format());
        _label->setPixmap(QPixmap::fromImage(*_modifiedImage));
    }
    else if (_slider->value() == 7)
    {
        float filterMatrix[49] =
        {
            0,  0,  0,  1,  0,  0,  0,
            0,  0,  1,  1,  1,  0,  0,
            0,  1,  1,  1,  1,  1,  0,
            1,  1,  1,  1,  1,  1,  1,
            0,  1,  1,  1,  1,  1,  0,
            0,  0,  1,  1,  1,  0,  0,
            0,  0,  0,  1,  0,  0,  0,
        };

        if (_matrix != 0)
            delete[] _matrix;

        _matrix = new float[49];
        _matrixWidth = 7;
        std::copy(std::begin(filterMatrix), std::end(filterMatrix), _matrix);

        _filter->set_original_data((int*)_image.bits(), _image.width(), _image.height());
        _filter->set_filter_matrix(filterMatrix, 7);
        _filter->set_bias(0.0);
        _filter->set_factor(1.0 / 25);

        _modifiedImage = new QImage((uchar*)_filter->use_filter(),
                                    _image.width(), _image.height(), _image.format());
        _label->setPixmap(QPixmap::fromImage(*_modifiedImage));
    }
}

/// Parameter: img: Small image for preview
///            parent: Parent widget
/// Return:
/// Action: Constructor
///         Constructs the dialog, connects the signals, sets members.
BlurDialog::BlurDialog(const QImage &img, QWidget *parent) : TransformationDialog(img, parent)
{
    _mainLayout = new QVBoxLayout;
    _subLayout = new QHBoxLayout;

    _okButton = new QPushButton("Ok");
    connect(_okButton, SIGNAL(clicked()), this, SLOT(accept()));

    _slider = new QSlider();
    _slider->setMinimum(3);
    _slider->setMaximum(7);
    _slider->setPageStep(2);
    connect(_slider, SIGNAL(valueChanged(int)), this, SLOT(slider_changed(int)));

    _subLayout->addWidget(_label);
    _subLayout->addWidget(_slider);

    _mainLayout->addLayout(_subLayout);
    _mainLayout->addWidget(_okButton);

    setLayout(_mainLayout);

    _filter = new Filter;
    _matrix = 0;

    _slider->setValue(5);

    setWindowTitle("Blur options");
}

/// Parameter:
/// Return:
/// Action: Destructor
BlurDialog::~BlurDialog()
{
    delete _filter;
    delete _modifiedImage;
    delete _slider;
    delete _okButton;
    delete _subLayout;
    delete _mainLayout;
    delete[] _matrix;
}

/// Parameter: matrixWidth: size of the returned matrix
/// Return: filter matrix
/// Action: Returns the filter matrix and it's size
float* BlurDialog::get_filter_matrix(int& matrixWidth)
{
    matrixWidth = _matrixWidth;
    return _matrix;
}
